/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
 * MemCache_Hybrid is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
*/
#include "mmc_mem_blob.h"
namespace ock {
namespace mmc {

const StateTransTable MmcMemBlob::stateTransTable_ = BlobStateMachine::GetGlobalTransTable();

Result MmcMemBlob::UpdateState(const std::string &key, uint32_t rankId, uint32_t operateId, BlobActionResult ret)
{
    auto curStateIter = stateTransTable_.find(state_);
    if (curStateIter == stateTransTable_.end()) {
        MMC_LOG_ERROR("Cannot update state! The current state " << state_ << " is not in the stateTransTable!");
        return MMC_UNMATCHED_STATE;
    }

    const auto retIter = curStateIter->second.find(ret);
    if (retIter == curStateIter->second.end()) {
        MMC_LOG_ERROR("cannot find " << std::to_string(ret) << " from " << std::to_string(state_));

        return MMC_UNMATCHED_RET;
    }

    MMC_LOG_DEBUG("update [" << key << "] state from " << std::to_string(state_) << " to ("
                            << std::to_string(retIter->second.state_) << ")");

    if (state_ == ALLOCATED && ret == MMC_WRITE_OK) {
        MMC_RETURN_ERROR(Backup(key), "memBlob remove use client error");
    }

    state_ = retIter->second.state_;
    if (retIter->second.action_) {
        auto res = retIter->second.action_(metaLeaseManager_, rankId, operateId);
        if (res != MMC_OK) {
            MMC_LOG_ERROR("Blob update current state is " << std::to_string(state_) << " by ret(" << std::to_string(ret)
                                                          << ") failed! res=" << res);
            return res;
        }
    }
    return MMC_OK;
}

Result MmcMemBlob::UpdateState(const BlobActionResult ret)
{
    auto curStateIter = stateTransTable_.find(state_);
    if (curStateIter == stateTransTable_.end()) {
        MMC_LOG_ERROR("Cannot update state! The current state " << state_ << " is not in the stateTransTable!");
        return MMC_UNMATCHED_STATE;
    }

    const auto retIter = curStateIter->second.find(ret);
    if (retIter == curStateIter->second.end()) {
        MMC_LOG_ERROR("cannot find " << std::to_string(ret) << " from " << std::to_string(state_));

        return MMC_UNMATCHED_RET;
    }

    state_ = retIter->second.state_;
    return MMC_OK;
}

Result MmcMemBlob::Backup(const std::string &key)
{
    MMCMetaBackUpMgrPtr mmcBackupPtr = MMCMetaBackUpMgrFactory::GetInstance("DefaultMetaBackup");
    if (mmcBackupPtr == nullptr) {
        MMC_LOG_ERROR("key " << key << " meta back up failed");
        return MMC_META_BACKUP_ERROR;
    }
    MmcMemBlobDesc desc = GetDesc();
    MMC_LOG_DEBUG("Backup add " << key << " rank " << desc.rank_);
    return mmcBackupPtr->Add(key, desc);
}

Result MmcMemBlob::BackupRemove(const std::string &key)
{
    MMCMetaBackUpMgrPtr mmcBackupPtr = MMCMetaBackUpMgrFactory::GetInstance("DefaultMetaBackup");
    if (mmcBackupPtr == nullptr) {
        MMC_LOG_ERROR("key " << key << " meta back up failed");
        return MMC_META_BACKUP_ERROR;
    }
    MmcMemBlobDesc desc = GetDesc();
    MMC_LOG_DEBUG("Backup remove " << key << " rank " << desc.rank_);
    return mmcBackupPtr->Remove(key, desc);
}

}  // namespace mmc
}  // namespace ock